#include<poisson.h>
#include <math.h>
#include <float.h>
#include <Windows.h>


#include<vector>

#include <SparseMatrix.h>
#include <PPolynomial.h>
#include <Ply.h>
#include <MultiGridOctreeData.h>

#define DEFAULT_FULL_DEPTH 5

#include <stdarg.h>


int execute_poisson(char * infile,char* outfile,int depth,float pointweight,float** points,unsigned int** polygons,int *p_size,int*po_size )
{
    Reset< float >();
    std::vector< char* > comments;
    XForm4x4< float > xForm , iXForm;
    xForm = XForm4x4< float >::Identity();
    iXForm = xForm.inverse();
    float isoValue = 0;
    Octree< float > tree;
        

    int kernelDepth = depth-2;
    
    tree.maxMemoryUsage=0;
    typename Octree< float >::template SparseNodeData< typename Octree< float >::PointData >* pointInfo = new typename Octree< float >::template SparseNodeData< typename Octree< float >::PointData >();
    typename Octree< float >::template SparseNodeData< Point3D< float > >* normalInfo = new typename Octree< float >::template SparseNodeData< Point3D< float > >();
    std::vector< float >* kernelDensityWeights = new std::vector< float >();
    std::vector< float >* centerWeights = new std::vector< float >();
    int pointCount;
    typedef typename Octree< float >::template ProjectiveData< Point3D< float > > ProjectiveColor;
    typename Octree< float >::template SparseNodeData< ProjectiveColor > colorData;

    OrientedPointStream< float >* pointStream;
    
    pointStream = new    PLYOrientedPointStream< float >(infile );
    printf("read ply\n");
 
                                   
    pointCount = tree.template SetTree< float >( pointStream , 0 , depth , 5 , kernelDepth , float(1.5) , 1.1 , false , false, pointweight , 1 , *kernelDensityWeights , *pointInfo , *normalInfo , *centerWeights , xForm , 1, false );
    printf("fsdfds\n");
    delete pointStream;
    delete kernelDensityWeights , kernelDensityWeights = NULL;


    float* constraints = tree.SetLaplacianConstraints( *normalInfo );
    delete normalInfo;
    

    float * solution = tree.SolveSystem( *pointInfo , constraints , false , 8 , depth , 0 , 1e-3 );
    delete pointInfo;
    SAFE_FREE( constraints );

    
    CoredFileMeshData< PlyVertex<float> > mesh;
    for(int i=0;i<9;i++)
    {
        printf("%lf\n",(*centerWeights)[i]);
    }
    isoValue = tree.GetIsoValue( solution , *centerWeights );
    delete centerWeights;
    tree.GetMCIsoSurface( kernelDensityWeights ? &((*kernelDensityWeights)[0]) : NULL ,  NULL , solution , isoValue , mesh , true , !false , false );
  //outOfCorePointCount 
    *points=(float*)malloc(sizeof(float)*mesh.outOfCorePointCount()*3);
    *p_size=mesh.outOfCorePointCount();
    *polygons=(unsigned int*)malloc(sizeof(unsigned int)*4*mesh.polygonCount()); 
    *po_size=mesh.polygonCount();
    PlyWritePolygons( outfile , &mesh , PLY_ASCII,*points,*polygons);
    //mesh.oocPointFile->reset();
    //PlyWritePolygons( outfile , &mesh , PLY_BINARY_NATIVE);
    
    SAFE_FREE( solution );
    return 1;
}